﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using io = System.IO;
using System.Threading;

namespace editor.app
{
    /// <summary>
    /// RSprite.xaml 的交互逻辑
    /// </summary>
    public partial class RSprite : UserControl, IResEditControl
    {
        comm.objst.RPack _rpack = null;
        comm.objst.RSprite _sprite = null;
        string _spriteResKey = "";
        string _threadId = "";

        string _groupKey = comm.objst.RSprite.DEFAULT_GROUP_KEY;

        Dictionary<string, CheckBox> _layerCkDic = new Dictionary<string, CheckBox>();
        Dictionary<string, Canvas> _layerDic = new Dictionary<string, Canvas>();
        Dictionary<string, CheckBox> _elCkDic = new Dictionary<string, CheckBox>();
        SpriteView _spriteView = null;

        const int PATH_SIZE = SpriteView.PATH_SIZE;
        public const int PATH_WIDTH = 100;
        public const int PATH_HEIGHT = 100;
        public const int LAYER_WIDTH = PATH_WIDTH * PATH_SIZE;
        public const int LAYER_HEIGHT = PATH_HEIGHT * PATH_SIZE;

        public RSprite(comm.objst.RPack rpack, string spriteResKey)
        {
            InitializeComponent();

            _rpack = rpack;
            _sprite = _rpack.GetResource<comm.objst.RSprite>(spriteResKey);
            _spriteResKey = spriteResKey;

            gridSelActionStep.Visibility = Visibility.Collapsed;

            #region res keys
            var tName = typeof(comm.objst.RSprite.Path).Name;
            cbResKeys.Items.Add(new TextBlock { Text = tName, Tag = new string[] { tName } });
            tName = typeof(comm.objst.RSprite.Label).Name;
            cbResKeys.Items.Add(new TextBlock { Text = tName, Tag = new string[] { tName } });
            var keys = _rpack.GetAllResourceKeys(typeof(comm.objst.RKeyFrameAnim), typeof(comm.objst.RImage));
            foreach (var key in keys)
            {
                var res = _rpack.GetResource(key);
                if (res != null)
                {
                    tName = res.GetType().Name;
                    var tb = new TextBlock { Tag = new string[] { tName, key } };
                    tb.Inlines.Add(new TextBlock
                    {
                        Text = tName,
                        Margin = new Thickness(0, 0, 4, 0),
                        Foreground = new SolidColorBrush(Color2.Black(50))
                    });
                    tb.Inlines.Add(new TextBlock { Text = res.Name });
                    cbResKeys.Items.Add(tb);
                }
            }
            cbResKeys.SelectedIndex = 0;
            #endregion

            #region layers
            var layers = comm.objst.DMap.Data.GetSpriteDesignLayerTypes();
            foreach (var layer in layers)
            {
                var ck = new CheckBox { Margin = new Thickness(0, 0, 0, 2), IsChecked = true, Focusable = false, };
                spLayers.Children.Add(ck);
                _layerCkDic.Add(layer, ck);

                var cv = new Canvas { Width = LAYER_WIDTH, Height = LAYER_HEIGHT };
                gridLayers.Children.Add(cv);
                _layerDic.Add(layer, cv);
            }
            #endregion

            _spriteView = new SpriteView(_layerDic, _rpack, _spriteResKey);
            _spriteView.CmdCallback = CmdCallback;

            brLayerHead.MouseLeftButtonDown += new MouseButtonEventHandler(brLayerHead_MouseLeftButtonDown);
            btnNewEl.Click += new RoutedEventHandler(btnNewEl_Click);
            svElKeys.ScrollChanged += new ScrollChangedEventHandler(svElKeys_ScrollChanged);
            svElList.ScrollChanged += new ScrollChangedEventHandler(svElList_ScrollChanged);
            btnEditEls.Click += new RoutedEventHandler(btnEditEls_Click);
            btnEditGroups.Click += new RoutedEventHandler(btnEditGroups_Click);
            Unloaded += new RoutedEventHandler(RSprite_Unloaded);
            btnNewGroup.Click += new RoutedEventHandler(btnNewGroup_Click);
            btnNewGroups.Click += new RoutedEventHandler(btnNewGroups_Click);
            btnClearGroup.Click += new RoutedEventHandler(btnClearGroup_Click);
            btnClone.Click += new RoutedEventHandler(btnClone_Click);
            btnSetActionStep.Click += new RoutedEventHandler(btnSetActionStep_Click);
            rspriteActionStep.OnCloseCallback = () =>
            {
                gridSelActionStep.Visibility = Visibility.Collapsed;
                FillElement();
            };

            Fill();

            #region loop
            _threadId = comm.ThreadHelper.Run(() =>
            {
                while (true)
                {
                    Dispatcher.Invoke(new Action(() =>
                    {
                        UpdateLayers();
                    }));
                    Thread.Sleep(100);
                }
            });
            #endregion
        }

        void btnClone_Click(object sender, RoutedEventArgs e)
        {
            var list = new List<string>();
            foreach (var key in _sprite.GroupDic.Keys)
            {
                if (key != comm.objst.RSprite.DEFAULT_GROUP_KEY)
                {
                    list.Add(key);
                }
            }
            foreach (var key in list)
            {
                _sprite.GetGroup(key).ElementDic.Clear();
            }
            _sprite.UpdateAllGroup();
            FillScene();
        }
        void btnEditGroups_Click(object sender, RoutedEventArgs e)
        {
            var window = new TextWindow { Width = 800, Height = 600 };
            window.InputText = comm.JsonSerializer.Serialize(_sprite.GroupDic, false, true);
            window.ShowDialog();

            try
            {
                var elDic = comm.JsonSerializer.Deserialize<Dictionary<string, comm.objst.RSprite.Group>>(window.InputText);
                if (elDic != null)
                {
                    _sprite.GroupDic = elDic;
                    Fill();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        void btnDelGroup_Click(object sender, RoutedEventArgs e)
        {
            var btn = (Button)sender;
            var parent = (FrameworkElement)btn.Parent;
            var key = parent.Tag.ToString();
            if (_sprite.GroupDic.ContainsKey(key))
            {
                _sprite.GroupDic.Remove(key);
                if (key == _groupKey)
                {
                    _groupKey = comm.objst.RSprite.DEFAULT_GROUP_KEY;
                }
                FillScene();
                FillGroup();
            }
        }
        void btnClearGroup_Click(object sender, RoutedEventArgs e)
        {
            var list = new List<string>();
            foreach (var key in _sprite.GroupDic.Keys)
            {
                if (key != comm.objst.RSprite.DEFAULT_GROUP_KEY)
                {
                    list.Add(key);
                }
            }
            foreach (var key in list)
            {
                _sprite.GroupDic.Remove(key);
            }
            _groupKey = comm.objst.RSprite.DEFAULT_GROUP_KEY;
            FillScene();
            FillGroup();
        }
        void btnNewGroups_Click(object sender, RoutedEventArgs e)
        {
            var types = comm.objst.DObject.Data.GetDirTypes();
            foreach (var type in types)
            {
                var key = comm.GUID.NewString();
                _sprite.GroupDic.Add(key, new comm.objst.RSprite.Group { Name = type });
            }
            _sprite.UpdateAllGroup();
            FillScene();
            FillGroup();
        }
        void btnNewGroup_Click(object sender, RoutedEventArgs e)
        {
            var key = comm.GUID.NewString();
            _sprite.GroupDic.Add(key, new comm.objst.RSprite.Group { Name = key });
            _sprite.UpdateAllGroup();
            FillScene();
            FillGroup();
        }
        void btnViewGroup_Click(object sender, RoutedEventArgs e)
        {
            var btn = (Button)sender;
            var parent = (FrameworkElement)btn.Parent;
            var key = parent.Tag.ToString();
            _groupKey = key;
            FillGroup();
            FillScene();
        }

        void RSprite_Unloaded(object sender, RoutedEventArgs e)
        {
            comm.ThreadHelper.Stop(_threadId);
        }
        void brLayerHead_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            var c = 0;
            foreach (var ck in _layerCkDic.Values)
            {
                c += ck.IsChecked.HasValue && ck.IsChecked.Value ? 1 : 0;
            }
            foreach (var ck in _layerCkDic.Values)
            {
                ck.IsChecked = c != _layerCkDic.Count;
            }
        }
        void btnEditEls_Click(object sender, RoutedEventArgs e)
        {
            var window = new TextWindow { Width = 800, Height = 600 };
            window.InputText = comm.JsonSerializer.Serialize(_sprite.GetGroup(_groupKey).ElementDic, false, true);
            window.ShowDialog();

            try
            {
                var elDic = comm.JsonSerializer.Deserialize<Dictionary<string, comm.objst.RSprite.Element>>(window.InputText);
                if (elDic != null)
                {
                    _sprite.GetGroup(_groupKey).ElementDic = elDic;
                    _sprite.UpdateAllGroup();
                    Fill();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        void svElKeys_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            svElList.ScrollToVerticalOffset(svElKeys.VerticalOffset);
        }
        void svElList_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            svElKeys.ScrollToVerticalOffset(svElList.VerticalOffset);
            svAction.ScrollToHorizontalOffset(svElList.HorizontalOffset);
        }
        void btnNewEl_Click(object sender, RoutedEventArgs e)
        {
            var tb = (TextBlock)cbResKeys.SelectedValue;
            var ss = (string[])tb.Tag;
            var key = comm.GUID.NewString();
            if (ss[0] == typeof(comm.objst.RSprite.Path).Name)
            {
                _sprite.GetGroup().ElementDic.Add(key, new comm.objst.RSprite.Path { Name = key });
            }
            else if (ss[0] == typeof(comm.objst.RSprite.Label).Name)
            {
                _sprite.GetGroup().ElementDic.Add(key, new comm.objst.RSprite.Label { Name = key });
            }
            else if (ss[0] == typeof(comm.objst.RKeyFrameAnim).Name)
            {
                _sprite.GetGroup().ElementDic.Add(key, new comm.objst.RSprite.KeyFrameAnim { Name = key, ResKey = ss[1] });
            }
            else if (ss[0] == typeof(comm.objst.RImage).Name)
            {
                _sprite.GetGroup().ElementDic.Add(key, new comm.objst.RSprite.Image { Name = key, ResKey = ss[1] });
            }
            _sprite.UpdateAllGroup();
            Fill();
        }
        void textboxKey_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textbox = (TextBox)sender;
            var parent = (FrameworkElement)textbox.Parent;
            var key = parent.Tag.ToString();

            var item = _sprite.GetGroup().ElementDic[key];
            item.Name = textbox.Text;
            _sprite.UpdateAllGroup();
            FillScene();
        }
        void btnDelKey_Click(object sender, RoutedEventArgs e)
        {
            var btn = (Button)sender;
            var parent = (FrameworkElement)btn.Parent;
            var key = parent.Tag.ToString();

            _sprite.GetGroup(_groupKey).ElementDic.Remove(key);
            _sprite.UpdateAllGroup();
            Fill();
        }
        void btnEditKey_Click(object sender, RoutedEventArgs e)
        {
            var btn = (Button)sender;
            var parent = (FrameworkElement)btn.Parent;
            var key = parent.Tag.ToString();
            EditElement(key);
        }
        void ckShow_Checked(object sender, RoutedEventArgs e)
        {
            FillScene();
        }
        void tbGroup_TextChanged(object sender, TextChangedEventArgs e)
        {
            var textbox = (TextBox)sender;
            var parent = (FrameworkElement)textbox.Parent;
            var key = parent.Tag.ToString();
            var item = _sprite.GetGroup(key);
            item.Name = textbox.Text;
            FillScene();
        }
        void btnSetActionStep_Click(object sender, RoutedEventArgs e)
        {
            gridSelActionStep.Visibility = Visibility.Visible;
            rspriteActionStep.Load(_rpack, _sprite);
        }

        void CmdCallback(string cmd, object[] args)
        {
            if (cmd == "edit")
            {
                EditElement(args[0].ToString());
            }
            else if (cmd == "delete")
            {
                _sprite.GetGroup(_groupKey).ElementDic.Remove(args[0].ToString());
            }
            else if (cmd == "setLayer")
            {
                var layer = (comm.objst.RSprite.ILayer)_sprite.GetGroup(_groupKey).ElementDic[args[0].ToString()];
                layer.MapLayerType = (comm.objst.MapLayerType)args[1];
            }
            else if (cmd == "labelMove")
            {
                _sprite.UpdateAllGroup();
            }
            else if (cmd == "fill")
            {
            }
            else if (cmd == "setImageByGroupName")
            {
                foreach (var groupKey in _sprite.GroupDic.Keys)
                {
                    var group = _sprite.GroupDic[groupKey];
                    foreach (var elKey in group.ElementDic.Keys)
                    {
                        if (elKey == args[0].ToString())
                        {
                            var kf = (comm.objst.RSprite.KeyFrameAnim)group.ElementDic[elKey];
                            var rkf = _rpack.GetResource<comm.objst.RKeyFrameAnim>(kf.ResKey);
                            foreach (var imageKey in rkf.ImageDic.Keys)
                            {
                                if (rkf.ImageDic[imageKey].Name.ToLower() == group.Name.ToLower())
                                {
                                    kf.ImageKey = imageKey;
                                    break;
                                }
                            }
                        }
                    }
                }
            }
            else if (cmd == "clone")
            {
                var key = args[0].ToString();
                var el = _sprite.GetGroup().ElementDic[key];
                foreach (var groupKey in _sprite.GroupDic.Keys)
                {
                    if (groupKey != comm.objst.RSprite.DEFAULT_GROUP_KEY)
                    {
                        var group = _sprite.GetGroup(groupKey);
                        if (args.Length == 2)
                        {
                            if (group.ElementDic[key] is comm.objst.RSprite.Label)
                            {
                                var key2 = args[1].ToString();
                                var label = (comm.objst.RSprite.Label)group.ElementDic[key];
                                label.PointDic.Remove(key2);
                            }
                        }
                        else
                        {
                            group.ElementDic.Remove(key);
                        }
                    }
                }
            }
            _sprite.UpdateAllGroup();
            Fill();
        }
        void EditElement(string key)
        {
            var dic = new Dictionary<string, comm.objst.RSprite.Element> { { key, _sprite.GetGroup(_groupKey).ElementDic[key] } };
            var window = new TextWindow { Width = 800, Height = 600 };
            window.InputText = comm.JsonSerializer.Serialize(dic, false, true);
            window.ShowDialog();

            try
            {
                var elDic = comm.JsonSerializer.Deserialize<Dictionary<string, comm.objst.RSprite.Element>>(window.InputText);
                if (elDic != null)
                {
                    _sprite.GetGroup(_groupKey).ElementDic[key] = elDic[key];
                    _sprite.UpdateAllGroup();
                    Fill();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
        void UpdateLayers()
        {
            foreach (var key in _layerCkDic.Keys)
            {
                var ck = _layerCkDic[key];
                var cv = _layerDic[key];
                cv.Visibility = ck.IsChecked == true ? Visibility.Visible : Visibility.Collapsed;
                ck.Visibility = cv.Children.Count > 0 ? Visibility.Visible : Visibility.Collapsed;
                ck.Content = new TextBlock { Text = key + "(" + cv.Children.Count + ")" };
            }
        }
        Grid MakeLine(string key, uint endTime1, uint endTime2, int height, comm.objst.RSprite.Element el)
        {
            var grid = new Grid { Height = height };
            grid.Children.Add(new Border
            {
                BorderBrush = new SolidColorBrush(Color2.Black(10)),
                BorderThickness = new Thickness(0, 0, 0, 1),
                Margin = new Thickness(0, 1, 0, 0)
            });
            if (!(el is comm.objst.RSprite.Timeline))
            {
                return grid;
            }
            uint offset = 0, endTime = endTime1;
            var tl = (comm.objst.RSprite.Timeline)el;
            var total = tl.GetTotalTime(_rpack);
            if (tl.StartType == comm.objst.RSprite.StartType.END)
            {
                offset = endTime1;
                endTime = endTime2;
            }
            if (tl.EndTime == null && tl.MaxLoopCount == null)
            {
                total = endTime - tl.BeginTime;
            }
            var resTotalTime = tl.GetResTotalTime(_rpack);
            if (total > 0)
            {
                grid.Children.Add(new Border
                {
                    Background = new SolidColorBrush(tl.StartType == comm.objst.RSprite.StartType.ZERO ? Color2.Black(10) : Color2.Black(20)),
                    BorderBrush = new SolidColorBrush(Color2.Black(50)),
                    BorderThickness = new Thickness(0, 0, 0, 1),
                    Margin = new Thickness(0, 1, 0, 0)
                });

                grid.HorizontalAlignment = HorizontalAlignment.Left;
                grid.Margin = new Thickness(tl.BeginTime + offset, 0, 0, 0);
                grid.Width = total;

                #region KeyFrameAnim
                if (resTotalTime > 0 && el is comm.objst.RSprite.KeyFrameAnim)
                {
                    var c = Math.Ceiling(total / (double)resTotalTime);
                    var times = tl.GetResTimes(_rpack);
                    for (int i = 0; i < c; i++)
                    {
                        var grid2 = new Grid
                        {
                            Width = resTotalTime,
                            Margin = new Thickness(i * resTotalTime, 0, 0, 0),
                            HorizontalAlignment = HorizontalAlignment.Left
                        };
                        uint ta = 0;
                        foreach (var t in times)
                        {
                            if (ta > 0)
                            {
                                grid2.Children.Add(new Rectangle
                                {
                                    Width = 2,
                                    Height = 4,
                                    Margin = new Thickness(ta, 2, 0, 0),
                                    Fill = new SolidColorBrush(Color2.Green(50)),
                                    HorizontalAlignment = HorizontalAlignment.Left,
                                    VerticalAlignment = VerticalAlignment.Top
                                });
                            }
                            ta += t;
                        }
                        grid2.Children.Add(new Border
                        {
                            Height = 6,
                            BorderBrush = new SolidColorBrush(Color2.Green(50)),
                            BorderThickness = new Thickness(0, 2, 2, 0),
                            Margin = new Thickness(0, 1, 0, 0),
                            VerticalAlignment = VerticalAlignment.Top
                        });
                        grid.Children.Add(grid2);
                    }
                }
                #endregion

                if (tl.EndTime != null || tl.MaxLoopCount != null)
                {
                    grid.Children.Add(new Border
                    {
                        Width = 6,
                        Height = 6,
                        Background = new SolidColorBrush(Color2.Black(50)),
                        HorizontalAlignment = HorizontalAlignment.Right
                    });
                }
            }

            #region contextMenu
            var contextMenu = new ContextMenu { FontSize = 14, Padding = new Thickness(0) };
            TextOptions.SetTextFormattingMode(contextMenu, TextFormattingMode.Display);
            var tbEdit = new TextBox { Width = 120, Height = 30, TextWrapping = TextWrapping.Wrap };
            var mEdit = new MenuItem { Header = tbEdit, Margin = new Thickness(0), Padding = new Thickness(0) };
            contextMenu.Opened += new RoutedEventHandler((o, e) =>
            {
                tbEdit.Text = (int)tl.StartType + "," + tl.MaxLoopCount + "," + tl.BeginTime + "," + tl.EndTime;
                tbEdit.Focus();
                tbEdit.SelectionStart = tbEdit.Text.Length;
                tbEdit.SelectionLength = 0;
            });
            contextMenu.Closed += new RoutedEventHandler((o, e) =>
            {
                var ss = tbEdit.Text.Split(',');
                if (ss.Length == 4)
                {
                    uint type = 0, loop, begin = 0, end;
                    bool typeOK = uint.TryParse(ss[0].Trim(), out type),
                        loopOK = uint.TryParse(ss[1].Trim(), out loop),
                        beginOK = uint.TryParse(ss[2].Trim(), out begin),
                        endOk = uint.TryParse(ss[3].Trim(), out end);
                    tl.BeginTime = begin;
                    if (typeOK)
                    {
                        var n = (comm.objst.RSprite.StartType)type;
                        if (Enum.IsDefined(typeof(comm.objst.RSprite.StartType), n))
                        {
                            tl.StartType = n;
                        }
                    }
                    if (loopOK)
                    {
                        tl.MaxLoopCount = loop;
                    }
                    else
                    {
                        tl.MaxLoopCount = null;
                    }
                    if (endOk)
                    {
                        tl.EndTime = end;
                    }
                    else
                    {
                        tl.EndTime = null;
                    }
                    FillElement();
                }
            });
            contextMenu.Items.Add(mEdit);
            grid.ContextMenu = contextMenu;
            #endregion

            return grid;
        }
        void Fill()
        {
            FillElement();
            FillScene();
            FillGroup();
        }
        void FillElement()
        {
            var ckKeys = new List<string>();
            var keys = _sprite.GetGroupAllElementKeys();
            spElKeys.Children.Clear();
            spElList.Children.Clear();
            gridElListMask.Children.Clear();
            foreach (var key in _elCkDic.Keys)
            {
                if (_elCkDic[key].IsChecked == true)
                {
                    ckKeys.Add(key);
                }
            }
            _elCkDic.Clear();

            var height = 20;
            var dmax = 100;

            var endTime1 = _sprite.GetGroupEndTime(_rpack);
            var endTime2 = _sprite.GetGroupEndTime(_rpack, comm.objst.RSprite.StartType.END);
            var totalTime = endTime1 + endTime2;
            var mcount = totalTime / dmax;

            #region 刻度head
            var gridTl = new Grid { Width = totalTime, Height = height, HorizontalAlignment = HorizontalAlignment.Left };
            gridTl.Children.Add(new Border { BorderBrush = new SolidColorBrush(Color2.Black(20)), BorderThickness = new Thickness(0, 0, 0, 1) });
            for (int i = 0; i < mcount; i++)
            {
                gridTl.Children.Add(new Border
                {
                    Child = new TextBlock { Text = i.ToString(), Foreground = new SolidColorBrush(Color2.Black(60)), },
                    Width = dmax,
                    Margin = new Thickness(i * dmax, 0, 0, 0),
                    BorderThickness = new Thickness(0, 0, 1, 0),
                    BorderBrush = new SolidColorBrush(Color2.Black(20)),
                    HorizontalAlignment = HorizontalAlignment.Left
                });
            }

            gridElListMask.Children.Add(new Border
            {
                Margin = new Thickness(endTime1 - 1, 20, 0, 0),
                BorderThickness = new Thickness(0, 0, 1, 0),
                BorderBrush = new SolidColorBrush(Color2.Black(50)),
                HorizontalAlignment = HorizontalAlignment.Left
            });
            #endregion

            spElKeys.Children.Add(new Border { Child = new TextBlock { Text = "ZERO:" + endTime1 + " END:" + endTime2 + ")", HorizontalAlignment = HorizontalAlignment.Center, VerticalAlignment = VerticalAlignment.Center }, Background = new SolidColorBrush(Color2.Black(10)), Height = height });
            spElList.Children.Add(gridTl);

            foreach (var key in keys)
            {
                var item = _sprite.GetGroupElement(key);
                var bitmap = new BitmapImage();
                var resKey = true;
                var tbText = "";

                spElList.Children.Add(MakeLine(key, endTime1, endTime2, height, item));

                #region icon
                string name = null;
                if (item is comm.objst.RSprite.Path)
                {
                    name = "path";
                }
                else if (item is comm.objst.RSprite.Label)
                {
                    name = "label";
                }
                else if (item is comm.objst.RSprite.KeyFrameAnim)
                {
                    name = "kfanim";
                    var kfanim = (comm.objst.RSprite.KeyFrameAnim)item;
                    resKey = _rpack.GetResource<comm.objst.RKeyFrameAnim>(kfanim.ResKey) != null;
                }
                else if (item is comm.objst.RSprite.Image)
                {
                    name = "image";
                    var image = (comm.objst.RSprite.Image)item;
                    resKey = _rpack.GetResource<comm.objst.RImage>(image.ResKey) != null;
                }
                if (name != null)
                {
                    bitmap.FromFile("icon/" + name + ".png");
                }
                #endregion

                if (item is comm.objst.RSprite.Timeline)
                {
                    var tl = (comm.objst.RSprite.Timeline)item;
                    var total = tl.GetTotalTime(_rpack).ToString();
                    tbText = total.ToString();
                    if (tl.EndTime == null && tl.MaxLoopCount == null)
                    {
                        tbText = (endTime1 - tl.BeginTime).ToString();
                    }
                }

                var grid = new Grid { Tag = key, Width = brEl.Width, Height = height };
                if (!resKey)
                {
                    grid.Opacity = .5;
                }

                var icon = new Image { Width = 16, Height = 16, Margin = new Thickness(22, 0, 0, 0), HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center };
                icon.Source = bitmap;

                var textbox = new TextBox
                {
                    Text = item.Name,
                    VerticalAlignment = VerticalAlignment.Center,
                    Margin = new Thickness(36, 0, 80, 0),
                    BorderThickness = new Thickness(0),
                    Background = null
                };
                textbox.TextChanged += new TextChangedEventHandler(textboxKey_TextChanged);

                var tb = new TextBlock { Width = 40, Text = tbText, TextAlignment = TextAlignment.Right, Foreground = new SolidColorBrush(Color2.Black(50)), VerticalAlignment = VerticalAlignment.Center, HorizontalAlignment = HorizontalAlignment.Right };

                var btnDel = new Button { Content = "X", Focusable = false, Width = 20, Height = 20, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center };
                btnDel.Click += new RoutedEventHandler(btnDelKey_Click);

                var btnEdit = new Button { Content = "E", Focusable = false, BorderThickness = new Thickness(0), Margin = new Thickness(0, 0, 40, 0), Width = 20, Height = 20, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center };
                btnEdit.Click += new RoutedEventHandler(btnEditKey_Click);

                var ckShow = new CheckBox { IsChecked = true, Focusable = false, Margin = new Thickness(0, 0, 64, 0), HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center };
                ckShow.Checked += new RoutedEventHandler(ckShow_Checked);
                ckShow.Unchecked += new RoutedEventHandler(ckShow_Checked);
                ckShow.IsChecked = ckKeys.Count == 0 || ckKeys.Contains(key);

                _elCkDic.Add(key, ckShow);

                grid.Children.Add(new Border { BorderThickness = new Thickness(0, 0, 0, 1), BorderBrush = new SolidColorBrush(Color2.Black(20)) });
                grid.Children.Add(btnDel);
                grid.Children.Add(icon);
                grid.Children.Add(textbox);
                grid.Children.Add(tb);
                grid.Children.Add(ckShow);
                grid.Children.Add(btnEdit);
                spElKeys.Children.Add(grid);
            }

            #region Action
            spAction.Children.Clear();
            spAction.Width = totalTime;
            spAction.Children.Add(new Border
            {
                Width = _sprite.BeginTime,
                Child = new TextBlock { Text = _sprite.BeginTime.ToString(), VerticalAlignment = VerticalAlignment.Center },
                Background = new SolidColorBrush(Color2.Orange(30))
            });
            spAction.Children.Add(new Border
            {
                Width = endTime1 - _sprite.BeginTime,
                Child = new TextBlock { Text = _sprite.ExecTime.HasValue ? _sprite.ExecTime.ToString() : "null", VerticalAlignment = VerticalAlignment.Center },
                Background = new SolidColorBrush(Color2.Green(50))
            });
            spAction.Children.Add(new Border
            {
                Width = _sprite.EndTime,
                Child = new TextBlock { Text = _sprite.EndTime.ToString(), VerticalAlignment = VerticalAlignment.Center },
                Background = new SolidColorBrush(Color2.Black(30))
            });
            _sprite.EndTime = endTime2;
            #endregion
        }
        void FillScene()
        {
            foreach (var key in _layerDic.Keys)
            {
                _layerDic[key].Children.Clear();
            }
            var cvGrid = _layerDic[comm.objst.MapLayerType.GRID.ToString()];
            for (int x = 1; x < PATH_WIDTH; x++)
            {
                var rect = new Rectangle { Width = 1, Height = LAYER_HEIGHT, Fill = new SolidColorBrush(Color2.White(20)) };
                rect.SetLeft(x * PATH_SIZE);
                cvGrid.Children.Add(rect);
            }
            for (int y = 1; y < PATH_HEIGHT; y++)
            {
                var rect = new Rectangle { Width = LAYER_WIDTH, Height = 1, Fill = new SolidColorBrush(Color2.White(20)) };
                rect.SetTop(y * PATH_SIZE);
                cvGrid.Children.Add(rect);
            }
            _spriteView.ChooseGroup(_groupKey);
            var showKeys = new List<string>();
            foreach (var key in _elCkDic.Keys)
            {
                if (_elCkDic[key].IsChecked == true)
                {
                    showKeys.Add(key);
                }
            }
            _spriteView.SetShow(showKeys.ToArray());
        }
        void FillGroup()
        {
            spGroups.Children.Clear();
            foreach (var key in _sprite.GroupDic.Keys)
            {
                var item = _sprite.GroupDic[key];
                var grid = new Grid { Tag = key };
                var tbGroup = new TextBox { Text = item.Name, BorderThickness = new Thickness(0), Margin = new Thickness(20, 0, 20, 0), VerticalAlignment = VerticalAlignment.Center };
                tbGroup.TextChanged += new TextChangedEventHandler(tbGroup_TextChanged);

                var btnDel = new Button { Content = "X", Focusable = false, Width = 20, Height = 20, HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Center };
                btnDel.Click += new RoutedEventHandler(btnDelGroup_Click);

                var btnView = new Button { Content = "V", Focusable = false, Width = 20, Height = 20, HorizontalAlignment = HorizontalAlignment.Right, VerticalAlignment = VerticalAlignment.Center };
                btnView.Click += new RoutedEventHandler(btnViewGroup_Click);

                if (key == comm.objst.RSprite.DEFAULT_GROUP_KEY)
                {
                    tbGroup.FontWeight = FontWeights.Bold;
                    tbGroup.IsReadOnly = true;
                }

                if (_groupKey == key)
                {
                    btnView.Background = new SolidColorBrush(Color2.Orange(70));
                }

                grid.Children.Add(tbGroup);
                if (key != comm.objst.RSprite.DEFAULT_GROUP_KEY)
                {
                    grid.Children.Add(btnDel);
                }
                grid.Children.Add(btnView);
                spGroups.Children.Add(grid);
            }
        }

        public void Reload()
        {
            Fill();
        }
        public string GetResKey()
        {
            return _spriteResKey;
        }
    }
}
